package edu.vt.ece.rt.quorum.messsages.types;

import org.jgroups.Address;

import edu.vt.ece.rt.dstm.Context;
import edu.vt.ece.rt.dstm.ContextDelegator;
import edu.vt.ece.rt.dstm.QObject;
import edu.vt.ece.rt.quorum.Resource;
import edu.vt.ece.rt.quorum.messsages.QMessage;
import edu.vt.ece.rt.quorum.messsages.QMessage.MessageType;
import edu.vt.ece.rt.util.Logger.Logger;

/*
 * Commit confirmation or Commit abortion request
 * @author Sudhanshu
 */

public class CommitConfirm extends QMessage implements Runnable {
	Context ct; 		//Specify the Context
	boolean commit;		//Specify read or write 

	public CommitConfirm(Context cxt, boolean c) {
		super(MessageType.CommitConfirm);
		ct = cxt;
		commit = c;
	}
	
	@Override
	public void run() {
		if(commit){
			Logger.debug("Commit Confirmed as Success "+ct.getContextId());
			ContextDelegator.getContext(ct.getContextId()).setCommited();
			ct.publishLocally();			//TODO: Think if require to check local copy
			for(QObject obj: ct.getWriteSet()){
				//Replace the new object, replaced old object will automatically collected by GC
				obj.updateVersion();
				Resource.updateObject(obj.getId(), obj);				
				Resource.getQObject(obj.getId()).unlockObject(ct.getContextId());	//Actually not required, as object is already replaced
				Logger.debug("Updated and Unlocked Object " + obj.getId() + " may Owned by tnx "+ct.getContextId());
			}			
		}else{
			Logger.debug("Commit Confirmed as Abort "+ct.getContextId());
			
			ContextDelegator.getContext(ct.getContextId()).setAborted();
			
			for(QObject obj: ct.getWriteSet()){
				Logger.debug("Aborted txn "+ct.getContextId()+" trying to release lock on "+obj.getId());
				Resource.getQObject(obj.getId()).unlockObject(ct.getContextId());
			}
		}
	}	
}
